﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Globalization;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using HQPad.Models;
using HQPad.Services;

namespace HQPad.Controllers
{
    public class SpellController : BaseController
    {
        private HQContext context = new HQContext();

        //
        // GET: /Spell/

        public ViewResult Index(int? id, string colour, string guild)
        {
            IRulesService rulesService = new RulesService(context);
            ISpellService spellService = new SpellService(context);
            //IGuildService guildService = new GuildService(context);

            if (!id.HasValue)
                id = rulesService.GetDefaultRules().RuleSetID;

            RuleSet rules = rulesService.GetRules(id.Value);
            PopulateRuleVersion(rules);
            PopulateMagicColours(null);

            var spells = spellService.GetSpells(id.Value);

            //// Get all guilds used
            //List<Guild> guilds = guildService.GetGuildsWithInvocations(rules.RuleSetID).ToList();

            //ViewBag.Guild = new SelectList(guilds, "Slug", "Name", guild != null && guild != "All" ? guild : "All");

            // Do any filters.
            if (colour != null && colour != "All")
                spells = spells.Where(i => i.Colour.ToLower() == colour.ToLower());

            //if (guild != null && guild != "All")
            //    spells = spells.Where(i => i.Guilds.Select(g => g.Slug).Contains(guild));


            return View(spells.ToList());
        }

        //
        // GET: /Spell/Create

        public ActionResult Create(int? ruleSetId)
        {
            IRulesService rulesService = new RulesService(context);
            
            PopulateMagicColours(null);
            PopulateStoreTypes(null);
            PopulateSpellLevels(null);

            if (!ruleSetId.HasValue)
                ruleSetId = rulesService.GetDefaultRules().RuleSetID;

            RuleSet rules = rulesService.GetRules(ruleSetId.Value);
            PopulateRuleVersion(rules);

            return View();
        } 

        //
        // POST: /Spell/Create

        [HttpPost]
        public ActionResult Create(Spell spell, FormCollection formCollection)
        {
            ISpellService spellService = new SpellService(context);
            IRulesService rulesService = new RulesService(context);

            string spellColour = formCollection["Colour"];
            ModelState.SetModelValue("Colour", new ValueProviderResult(spellColour, spellColour, new CultureInfo("en-GB")));

            string storeType = formCollection["StoreType"];
            ModelState.SetModelValue("StoreType", new ValueProviderResult(storeType, storeType, new CultureInfo("en-GB")));

            string level = formCollection["Level"];
            ModelState.SetModelValue("Level", new ValueProviderResult(level, level, new CultureInfo("en-GB")));

            spell.Deleted = false;
            spell.LastUpdated = DateTime.Now;
            spell.LastUpdatedByUserID = 1;

            // Create a spell slug from the spell name.
            string slug = spellService.CreateSpellSlug(spell.Name);

            // Try and get a spell with this slug to check for uniqueness.
            Spell existingSpell = spellService.GetSpell(spell.RuleSetID, slug);

            if (existingSpell != null)
            {
                ModelState.AddModelError("Slug", string.Format("Unable to save changes. The generated spell slug {0} already exists in the system, try a different spell name.", slug));
            }
            else
            {
                ModelState.SetModelValue("Slug", new ValueProviderResult(slug, slug, new CultureInfo("en-GB")));
                spell.Slug = slug;
                ModelState["Slug"].Errors.Clear();
            }

            TryUpdateModel(spell);


            if (ModelState.IsValid)
            {
                spellService.Add(spell);
                context.Save();
                return RedirectToAction("Index");  
            }
            RuleSet rules = rulesService.GetRules(spell.RuleSetID);
            PopulateRuleVersion(rules);

            return View(spell);
        }
        
        //
        // GET: /Spell/Edit/5
 
        public ActionResult Edit(int? ruleSetId, string slug)
        {
            ISpellService spellService = new SpellService(context);
            IRulesService rulesService = new RulesService(context);

            if (ruleSetId.HasValue)
            {
                RuleSet rules = rulesService.GetRules(ruleSetId.Value);
                PopulateRuleVersion(rules);
            }

            Spell spell = spellService.GetSpell(ruleSetId.Value, slug);

            PopulateMagicColours(spell.Colour);
            PopulateStoreTypes(spell.StoreType);
            PopulateSpellLevels(spell.Level);

            return View(spell);
        }

        //
        // POST: /Spell/Edit/5

        [HttpPost]
        public ActionResult Edit(Spell spell)
        {
            IRulesService rulesService = new RulesService(context);

            spell.LastUpdated = DateTime.Now;
            spell.LastUpdatedByUserID = 1; // todo: Add current user id.

            if (ModelState.IsValid)
            {
                ISpellService spellService = new SpellService(context);

                spellService.UpdateSpell(spell);

                context.Save();

                return RedirectToAction("Index");
            }

            PopulateMagicColours(spell.Colour);
            PopulateStoreTypes(spell.StoreType);
            PopulateSpellLevels(spell.Level);

            RuleSet rules = rulesService.GetRules(spell.RuleSetID);
            PopulateRuleVersion(rules);

            return View(spell);
        }

        ////
        //// GET: /Spell/Delete/5

        public ActionResult Delete(int ruleSetId, string slug)
        {
            ISpellService spellService = new SpellService(context);
            Spell spell = spellService.GetSpell(ruleSetId, slug);

            if (spell != null)
            {
                spellService.DeleteSpell(spell.SpellID);
                context.Save();
            }

            return RedirectToAction("Index", new { id = ruleSetId });
        }

        protected override void Dispose(bool disposing)
        {
            context.Dispose();
            base.Dispose(disposing);
        }

        protected void PopulateMagicColours(string selectedColour)
        {
            ViewBag.Colour = new SelectList(Enum.GetNames(typeof(SpellColour)), selectedColour);
        }

        protected void PopulateStoreTypes(string selectedStore)
        {
            ViewBag.StoreType = new SelectList(Enum.GetNames(typeof(StoreType)), selectedStore);
        }

        protected void PopulateSpellLevels(int? selectedLevel)
        {
            ViewBag.Level = new SelectList(new int[10]{1,2,3,4,5,6,7,8,9,10}, selectedLevel.HasValue ? selectedLevel.Value : 0);
        }
    }
}